package nachos.threads;

import nachos.machine.*;

/**
 * 多线程操作系统内核
 */
public class ThreadedKernel extends Kernel {
    /**
     * 分配一个新的多线程内核
     */
    public ThreadedKernel() {
        super();
    }

    /**
     * 初始化这个内核
     * 创建调度程序、第一个线程和警报器，并启用中断
     * 如有必要，创建文件系统
     */
    public void initialize(String[] args) {
        // set scheduler
        String schedulerName = Config.getString("ThreadedKernel.scheduler");
        scheduler = (Scheduler) Lib.constructObject(schedulerName);

        // set fileSystem
        String fileSystemName = Config.getString("ThreadedKernel.fileSystem");
        if (fileSystemName != null)
            fileSystem = (FileSystem) Lib.constructObject(fileSystemName);
        else if (Machine.stubFileSystem() != null)
            fileSystem = Machine.stubFileSystem();
        else
            fileSystem = null;

        // start threading
        new KThread(null);

        alarm = new Alarm();

        Machine.interrupt().enable();
    }

    /**
     * 测试这个内核
     * 测试 KThread 类、Semaphore 类、SynchList 类和 ElevatorBank 类
     * 请注意，autograder 从不调用此方法，因此在此处放置其他测试是安全的
     */
    public void selfTest() {
        KThread.selfTest();
        Semaphore.selfTest();
        SynchList.selfTest();
        if (Machine.bank() != null) {
            ElevatorBank.selfTest();
        }
    }

    /**
     * 线程内核不运行用户程序，因此此方法不执行任何操作
     */
    public void run() {
    }

    /**
     * 终止此内核，永远不会返回
     */
    public void terminate() {
        Machine.halt();
    }

    /**
     * 对调度程序的全局可访问引用
     */
    public static Scheduler scheduler = null;
    /**
     * 对警报器的全局可访问引用
     */
    public static Alarm alarm = null;
    /**
     * 对文件系统的全局可访问引用
     */
    public static FileSystem fileSystem = null;

    // dummy variables to make javac smarter
    private static RoundRobinScheduler dummy1 = null;
    private static PriorityScheduler dummy2 = null;
    private static LotteryScheduler dummy3 = null;
    private static Condition2 dummy4 = null;
    private static Communicator dummy5 = null;
    private static Rider dummy6 = null;
    private static ElevatorController dummy7 = null;
}
